package com.ruoyi.system.service.carte;


import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpStatus;
import com.alibaba.fastjson.JSON;
import com.ruoyi.common.utils.StaxonUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.XxkCarte;
import com.ruoyi.system.domain.XxkCarteRuns;
import com.ruoyi.system.domain.request.BaseTransRequest;
import com.ruoyi.system.domain.request.JobExecuteRequest;
import com.ruoyi.system.domain.request.TransExecuteRequest;
import com.ruoyi.system.service.IXxkCarteRunsService;
import com.ruoyi.system.service.IXxkCarteService;
import com.ruoyi.system.xxkutil.XxkUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.MapUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;

@Slf4j
@Service
public abstract class AbstractCarteService {

    @Autowired
    private IXxkCarteService xxkCarteService;

    @Autowired
    private IXxkCarteRunsService xxkCarteRunsService;

    protected String commonHandle(BaseTransRequest transRequest) throws Exception{
        //根据carteCode 查询carte信息
        XxkCarte xxkCarte = null;
        if(StringUtils.isNotEmpty(transRequest.getCarteCode())){
            xxkCarte = xxkCarteService.selectXxkCarteByCarteCode(transRequest.getCarteCode());
        }else{
           List<XxkCarte> xxkCarteList =  xxkCarteService.selectXxkCarteByGroupName(transRequest.getGroupName());
            xxkCarte = XxkUtils.getOneCarte(xxkCarteList,transRequest);
        }
        if(null==xxkCarte){
            throw new Exception("carte配置不存在");
        }
        boolean saveFlag=false;
        if(transRequest instanceof TransExecuteRequest||transRequest instanceof JobExecuteRequest){
            saveFlag=true;
        }
        //
        XxkCarteRuns xxkCarteRuns =  new XxkCarteRuns();
        if(saveFlag){
            BeanUtils.copyProperties(xxkCarte,xxkCarteRuns);
            xxkCarteRuns.setId(null);
            xxkCarteRuns.setCarteId(xxkCarte.getId());
            if(transRequest instanceof TransExecuteRequest){
                TransExecuteRequest request =(TransExecuteRequest)transRequest;
                xxkCarteRuns.setName(request.getName());
                xxkCarteRuns.setRep(request.getRep());
                xxkCarteRuns.setRunLevel(request.getLevel());
                xxkCarteRuns.setParmMap(JSON.toJSONString(request.getParmMap()));
                xxkCarteRuns.setItemType("trans");
                xxkCarteRuns.setPolicy(request.getPolicy());
                xxkCarteRuns.setSync(request.isSync()+"");
            }
            if(transRequest instanceof JobExecuteRequest){
                JobExecuteRequest request =(JobExecuteRequest)transRequest;
                xxkCarteRuns.setName(request.getName());
                xxkCarteRuns.setRep(request.getRep());
                xxkCarteRuns.setRunLevel(request.getLevel());
                xxkCarteRuns.setParmMap(JSON.toJSONString(request.getParmMap()));
                xxkCarteRuns.setItemType("job");
                xxkCarteRuns.setPolicy(request.getPolicy());
                xxkCarteRuns.setSync(request.isSync()+"");
            }
        }

        //封装调用参数
        setRequestUrl(xxkCarte,transRequest);
        //执行调用
        if(transRequest.isSync()){
            //同步
            String xmlResult="";
            try{
                xmlResult= sendTransRequest(transRequest,xxkCarte);
                if(saveFlag) {
                    xxkCarteRuns.setRunStatus("成功");
                    xxkCarteRuns.setSync("同步");
                    xxkCarteRuns.setRunResult(xmlResult);
                    xxkCarteRuns.setCarteObjectId(getCarteObjectId(xmlResult));
                    xxkCarteRunsService.insertXxkCarteRuns(xxkCarteRuns);
                }
            }catch (Exception e){
                if(saveFlag) {
                    xxkCarteRuns.setRunStatus("失败");
                    xxkCarteRuns.setRunResult(e.getMessage());
                    xxkCarteRunsService.insertXxkCarteRuns(xxkCarteRuns);
                }
                throw e;
            }
            if(transRequest.getParmMap()!=null&&"Y".equalsIgnoreCase(MapUtils.getString(transRequest.getParmMap(),"xml"))){
                return StaxonUtils.xml2json(xmlResult);
            }else{
                return xmlResult;
            }
        }else{
            //异步非阻塞
            try{
                sendTransRequestAsync(transRequest,xxkCarte);
                if(saveFlag) {
                    xxkCarteRuns.setRunStatus("成功");
                    xxkCarteRuns.setSync("异步");
                    xxkCarteRuns.setRunResult("");
                    xxkCarteRunsService.insertXxkCarteRuns(xxkCarteRuns);
                }
            }catch (Exception e){
                if(saveFlag) {
                    xxkCarteRuns.setRunStatus("失败");
                    xxkCarteRuns.setRunResult(e.getMessage());
                    xxkCarteRunsService.insertXxkCarteRuns(xxkCarteRuns);
                }
                throw e;
            }
            return "ok";
        }
    }


    private String getCarteObjectId(String xmlResult){
        if(org.apache.commons.lang3.StringUtils.isNotEmpty(xmlResult)){
            try{
                Map<String,Object> map = StaxonUtils.xml2Map(xmlResult);
                Map<String,Object>  webresult =MapUtils.getMap(map,"webresult");
                return MapUtils.getString(webresult,"id");
            }catch (Exception ex){
                log.error(ex.getMessage(),ex);
                return "";
            }
        }
        return "";
    }
    protected String commonHandle(BaseTransRequest transRequest, HttpServletResponse response) throws Exception{
        //根据carteCode 查询carte信息
        XxkCarte xxkCarte = xxkCarteService.selectXxkCarteByCarteCode(transRequest.getCarteCode());
        if(null==xxkCarte){
            throw new Exception("carte配置不存在");
        }
        //封装调用参数
        setRequestUrl(xxkCarte,transRequest);
        //执行调用
        return sendTransRequest(transRequest,xxkCarte,response);

    }

    protected  abstract  void setRequestUrl(XxkCarte xxkCarte, BaseTransRequest baseTransRequest)throws Exception;

    public  String sendTransRequestAsync(BaseTransRequest transRequest, XxkCarte xxkCarte) throws Exception {
        CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
            try {
                sendTransRequest(transRequest,xxkCarte);
            } catch (Exception e) {
               log.error(e.getMessage(),e);
            }
        });
        //future.join() 的作用是等待异步任务执行完成。在调用这个方法之前，主线程会继续执行其他操作，但是当遇到 future.join() 方法时，主线程会被阻塞，直到异步任务执行完成
        //future.join();
        return "ok";
    }
    public  String sendTransRequest(BaseTransRequest transRequest, XxkCarte xxkCarte) throws Exception {
        HttpRequest httpRequest = HttpRequest.post(transRequest.getRequestUrl());
        //设置header
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Type","application/x-www-form-urlencoded");
        httpRequest.header(headers);
        //auth
        httpRequest.basicAuth(xxkCarte.getCarteUsername(),xxkCarte.getCartePassword());
        //10s
        httpRequest.setConnectionTimeout(10000);
        //1分钟
        httpRequest.setReadTimeout(1*60*1000);

        if(null!=transRequest.getParmMap()){
            httpRequest.form(transRequest.getParmMap());
        }

        HttpResponse httpResponse = httpRequest.execute();
        int code = httpResponse.getStatus();
        if ( code >= HttpStatus.HTTP_BAD_REQUEST ) {
            log.error( "启动trans出错" );
        }
        return httpResponse.body();
    }

    public  String sendTransRequest(BaseTransRequest transRequest, XxkCarte xxkCarte,HttpServletResponse response) throws Exception {
        HttpRequest httpRequest = HttpRequest.post(transRequest.getRequestUrl());
        //设置header
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Type","application/x-www-form-urlencoded");
        httpRequest.header(headers);
        //auth
        httpRequest.basicAuth(xxkCarte.getCarteUsername(),xxkCarte.getCartePassword());
        //10s
        httpRequest.setConnectionTimeout(10000);
        //1分钟
        httpRequest.setReadTimeout(1*60*1000);

        if(null!=transRequest.getParmMap()){
            httpRequest.form(transRequest.getParmMap());
        }

        HttpResponse httpResponse = httpRequest.execute();
        int code = httpResponse.getStatus();
        if ( code >= HttpStatus.HTTP_BAD_REQUEST ) {
            log.error( "启动trans出错" );
            return "error";
        }

        response.setContentType("image/png");
        // 这里可以根据实际情况获取图像数据并写入响应流
        byte[] imageData = httpResponse.bodyBytes(); // 假设您已经获取了图像数据
        response.getOutputStream().write(imageData);
        return "ok";
    }


}
